<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<link rel="stylesheet" href="../style/journal.css" type="text/css" />
<style type="text/css"><!--
.googleadsense {
	margin: 2px;
	padding: 0px;
//--></style><script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-65008-1";
urchinTracker();
</script><title>Ajax && encodeURIComponent</title>
</head>
<body>
<a href="index.html">Journal</a>(2005) | <a href="../blog/"><b>Blog</b></a>(2006) | <a href="http://www.fayland.org/cgi-bin/random_link.pl">RandomLink</a> | <a href="AboutFayland.html">WhoAmI</a> | <a href="LiveBookmark.html">LiveBookmark</a> | <a href="http://www.fayland.org/">HomePage</a>
<p><&lt;Previous: <a href="Ajax_url.html">Ajax 网址备忘</a>&nbsp;&nbsp;>>Next: <a href="irclogger_link.html">获取 IRC logger 里的链接</a></p>
<h1>Ajax && encodeURIComponent</h1>
<div class='content'>
<p>Category: <a href='Javascript.html'>Javascript</a> &nbsp; Keywords: <b>Javascript Ajax 中文编码</b></p><p>今天闲着无事就想着用 Ajax 实现论坛的用户名检测。</p>

<p>先简化了下 Ajax.js, 让它能在不同的程序里指定不同的 url, param 和 div 的 id.<br />
<pre><code>
var req, Div;
var debug = 0;

function Ajax(DivName, url, parameters) {
    if (window.XMLHttpRequest) req = new XMLHttpRequest();
    else if (window.ActiveXObject) req = new ActiveXObject("Microsoft.XMLHTTP");
    else return; // fall on our sword
    req.onreadystatechange = processReqChange;
    req.open("POST", url, true);
    req.setRequestHeader('Connection', 'close');
    req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
    req.send(parameters);
    Div = document.getElementById(DivName);
}

function processReqChange() {
    // only if req shows "complete"
    if (req.readyState == 4) {
        // only if "OK"
        if (req.status == 200) {
            // show content in div
            Div.innerHTML = req.responseText;
        } else {
            if (debug) alert('status is not 200,but ' + req.status);
        }
    }
}</code></pre>
调用的代码为：
<pre><code>&lt;input type="text" maxlength="12" name="username" onblur="CheckName(this.value)"> * 2 - 12 字符（1 - 6 汉字）
&lt;script language="javascript" type="text/javascript" src="./js/Ajax.js">&lt;/script>
&lt;script language="javascript" type="text/javascript">
    function CheckName(aObj) {
        try { Ajax('CheckName', 'CheckName.pl', 'mode=Ajax&name=' + encodeURIComponent(aObj)); }
        catch (e) { return; }
    }
&lt;/script>
&lt;div id="CheckName">&lt;/div></code></pre>
Update: 感谢 <a href='http://www.easunstudio.com'>easunlee</a> 的提醒， encodeURIComponent 对 IE5.5 以下无效，所以我们用了 try+catch 在无效情况下不调用该函数（和|或者）弹出 alert 提示升级浏览器。

<h2>问题出现了</h2>
首先解释下 encodeURIComponent 的作用：将文本字符串编码为一个有效的统一资源标识符 (URI)。<br />
为什么要用这个是因为我想把 username 整个当做参数传递给 CGI, 而不让 CGI 将 username 分割掉。这话听不明白的话我换种方式来说，如果 username = 'a&foo=boo' 而不用 encodeURIComponent 的话，整个参数就成了 name=a&foo=boo, 这样 CGI 就获得两个参数 name 和 foo. 这不是我们想要的。<br />
Javascript 里还有个同样功能的函数 encodeURI, 但是此方法不会对下列字符进行编码：":"、"/"、";" 和 "?"。

<p>刚开始我都输入英文检测代码是否运行正常，后来因为我不想用户名为“客人”，所以就试了下。<br />
结果很令我奇怪，div 为 CheckName 里的输出是“瀹汉”。<br />
一看到这个，第一反应就是编码问题。</p>

<p>客人经过 JS 的 encodeURIComponent 转化后得到的值为 %E5%AE%A2%E4%BA%BA, 而我直接在浏览器里输出客人后转的值为 %BF%CD%C8%CB. 辨别后，猜测 Javascript encodeURIComponent 将“客人”转为了 utf-8 编码。</p>

<p>于是在 CheckName.pl 里加了编码转换。
<pre><code>use Encode qw/from_to/;
my $name = $q->param('name');
from_to($name, "utf8", "gb2312");</code></pre>
终于搞定。</p>

<h2>The last words</h2>
希望对碰到同样问题的各位能有所帮助。 Have fun!</div>
<p><&lt;Previous: <a href="Ajax_url.html">Ajax 网址备忘</a>&nbsp;&nbsp;>>Next: <a href="irclogger_link.html">获取 IRC logger 里的链接</a></p>
<p><strong>Options:</strong> <a href='http://del.icio.us/post?title=Ajax%20&&%20encodeURIComponent&url=http://www.fayland.org/journal/JS_encode.html'>+Del.icio.us</a></p>
<strong>Related items</strong>
<ul><li><a href='JS_event.html'>Javascript: Events</a> < <span class='digit'>2005-05-10 23:36:36</span> ></li><li><a href='AutoSave.html'>AutoSave / 自动存储</a> < <span class='digit'>2005-10-14 01:26:10</span> ></li><li><a href='Ajax_url.html'>Ajax 网址备忘</a> < <span class='digit'>2005-04-08 19:44:12</span> ></li><li><a href='Ajax_preview.html'>用 Ajax 技术添加预览功能</a> < <span class='digit'>2005-04-10 01:35:28</span> ></li></ul>
Created on <span class="digit">2005-05-15 15:31:00</span>, Last modified on <span class="digit">2005-10-14 00:58:51</span><br />
Copyright 2004-2005 All Rights Reserved. Powered by <a href="Eplanet.html">Eplanet</a> && <a href='http://catalyst.perl.org'>Catalyst</a> 5.62.
</body>
</html>